#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <mutex>
#include <atomic>
#include "singleton.hpp"

namespace rsv{

    class Logger : public rsv::singleton<Logger, true> {
    public:
        enum class Level {
            INFO,
            WARNING,
            ERROR
        };

        void log(Level level, const std::string& message) {
            std::lock_guard<std::mutex> lock(mtx);
            std::cout << message << std::endl;
            switch (level) {
                case Level::INFO:
                    logFile << "INFO: " << message << std::endl;
                    break;
                case Level::WARNING:
                    logFile << "WARNING: " << message << std::endl;
                    break;
                case Level::ERROR:
                    logFile << "ERROR: " << message << std::endl;
                    break;
            }
        }
    private:
        std::mutex mtx;
        std::ofstream logFile;
    public:
        Logger() : logFile("log.txt", std::ios::app) {
            if (!logFile) {
                std::cout << "Logger: Failed to open log file" << std::endl;
            }
        }

        ~Logger() {
            //std::cout << "Logger destructed\n"; 
            pInstance_ = nullptr;
            destroyed_ = true; 
            //b_init_ = false;
            //b_init_.store(false, std::memory_order_release);

            logFile.close();
        }

        friend class rsv::singleton<Logger, true>;
    };

    #define LOG(level, message) Logger::instance().log(level, message)
}